/**
 * FileName: FloatFieldEncoder
 * Author:   zhaoxiaoqiang
 * Date:     2019/8/21 8:05
 * Description: 浮点数转二进制
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.zxq.factory.encoder.impl;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
import com.zxq.factory.encoder.IFieldEncoder;
import com.zxq.memory.ByteCombination;

/**
 * 〈浮点数转二进制〉
 *
 * @author zhaoxiaoqiang
 * @date 2019/8/21
 * @since 1.0.0
 */
public class FloatFieldEncoder implements IFieldEncoder<Float> {

    /**
     * float就默认4个字节，其他不理会
     * @param value 数值
     * @param size 大小
     * @return
     */
    IntFieldEncoder intFieldEncoder = new IntFieldEncoder();
    @Override
    public byte[] encoder(Float value, int size) {

        if(size != 4 ) {
            System.out.println("float 只支持32");
            return null;
        }
        Float positiveValue = Math.abs(value);
      //  System.out.println("positiveValue: " + positiveValue);
        // 2的负几次方小于1
        Integer exponent = countExponent(positiveValue);
     //   System.out.println("exponent: " + exponent);
        //阶码 0.1111 移后 1.111
        //移码 保存方式
        Double shiftFrame = Math.pow(2,7) - 1;
        //阶码 + 移码 保存方式
        Integer shiftCode = shiftFrame.intValue() + exponent;
        //阶码的最后一位，会成为尾数的最高位，占1bit
        Integer tailOneByte = shiftCode % 2;

        byte shiftExponent = (byte) (shiftCode >> 1);
        if(value < 0) {
            //符号位小于零，最高位补1
           shiftExponent = (byte) (shiftExponent + 128);
        }

        byte[] exponentBuff = new byte[]{shiftExponent};

      //  System.out.println("exponent buff:" + HexBin.encode(exponentBuff));

        //小数点右后，原来int值，变化成的float数值,1.xxx * Math.pow(2,exponent)中的 1.xxx的值
        Double floatValue = positiveValue * Math.pow(2, -exponent);
      //  System.out.println("decimal tail:" + floatValue);

        Double tailUnit = Math.pow(2.0,23);
        Double tailValue = (floatValue -1) * tailUnit;
     //   System.out.println("tailValue:" + tailValue);
        byte[] tailBuff = intFieldEncoder.encoder(tailValue.intValue(),3);
     //   System.out.println("tailHex:" + HexBin.encode(tailBuff));

        //阶数的最后一位，移动到尾数的第一位
        tailBuff[0] = (byte) (tailOneByte * Math.pow(2,7) + tailBuff[0]);

        byte[] totalBuff = ByteCombination.combinationContent(exponentBuff,tailBuff);

        //System.out.println("IEEE754:" + HexBin.encode(totalBuff));
        return totalBuff;

    }

    // param 0, return 1;  param 1,return 1;  param 2,return 1;  param 3, return 2
    // param 4, return 2;  param 5.return 3;  param 5,return 3;  param 7, return 3
    private  Integer countExponent(Float value) {

        /**
         * 从-1开始，最低单位是1
         */
        Integer exponent = 0;
        Double intUnit = 1.0;
        if(value > 1) {
            while (!((value / intUnit) > 1 && (value / intUnit) < 2)) {
                exponent ++;
                intUnit = Math.pow(2, exponent);
//                System.out.println("unit value:" + intUnit);
//                System.out.println("tail value:" + value/intUnit);
            }
       } else if(value == 1.0f){
            exponent = 0;
        } else {
            while ( !((value / intUnit) > 1 && (value / intUnit) < 2) ) {
                exponent --;
                intUnit = Math.pow(2, exponent);
//                System.out.println("unit value:" + intUnit);
//                System.out.println("tail value:" + value/intUnit);
            }
        }

        return exponent;
    }




//    public static void main(String[] args) {
//
//        Float fValue = 20.59375f;
//        FloatFieldEncoder floatFieldEncoder = new FloatFieldEncoder();
//        byte[] hexBuff = floatFieldEncoder.encoder(fValue,4);
//        System.out.println("index:"  + HexBin.encode(hexBuff) );
//    }















}
